package com.project.poetry.common.util;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

//@Component
public class QuartzUtil {

    /**
     * 单例
     */
    @Resource
    private  Scheduler scheduler;// = createScheduler();

    private static final String JOB_GROUP = "jobGroup";
    private static final String TRIGGER_GROUP = "triggerGroup";
   // private static final Class<EvaluationPlanJob> clazz = EvaluationPlanJob.class;

    /**
     * 创建一个触发器
     * @param cron
     * @param triggerKeyName
     * @param endDate
     * @return
     */
    private static Trigger createTrigger(String cron, String triggerKeyName, Date endDate) {
        return TriggerBuilder.newTrigger().withIdentity(triggerKeyName,TRIGGER_GROUP)
                .withSchedule(CronScheduleBuilder.cronSchedule(cron)
                        .withMisfireHandlingInstructionDoNothing()).endAt(endDate).build();
    }

    /**
     * 创建一个调度器
     */
    public static  Scheduler createScheduler() {
        SchedulerFactory schedulerfactory = new StdSchedulerFactory();
        try {
            return schedulerfactory.getScheduler();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return null;
    }

//    /**
//     * 创建作业
//     * @param jobName
//     * @param dataMap
//     * @return
//     */
//    private static JobDetail getJob( String jobName, JobDataMap dataMap) {
//        return JobBuilder.newJob(clazz).setJobData(dataMap).withIdentity(jobName,JOB_GROUP).build();
//    }

    /**
     * 获取Job信息
     * @param key
//     * @return
//     */
//    private static JobDetail getDetail(String key) {
//        JobKey jobKey = JobKey.jobKey(key, JOB_GROUP);
//        JobDetail detail =null;
//        try {
//            detail = scheduler.getJobDetail(jobKey);
//        } catch (SchedulerException e1) {
//            e1.printStackTrace();
//        }
//        return detail;
//    }

    /**
     * 开启一次调度
     * @param scheduler
     * @param jobDetail
     * @param trigger
     */
    private static void startScheduler(Scheduler scheduler, JobDetail jobDetail, Trigger trigger) {
        try {
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加一个调度
     * @param scheduler
     * @param jobDetail
     * @param trigger
     */
    private static void addScheduler(Scheduler scheduler, JobDetail jobDetail, Trigger trigger) {
        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将作业的字符串类型keyId转成对象类型集合
     * @param keyArray JobKey数组
     * @return JobKey对象集合
     */
    private static List<JobKey> getJobKeys(String[] keyArray) {
        List<JobKey> jobKeys = new ArrayList<>();
        for (int i = 0; i < keyArray.length; i++) {
            String key = keyArray[i];
            jobKeys.add(JobKey.jobKey(key, JOB_GROUP));
        }
        return jobKeys;
    }

    /**
     * 将作业的字符串类型TriggerKey转成对象类型集合
     * @param keyArray TriggerKey数组
     * @return TriggerKey对象集合
     */
    private static List<TriggerKey> getTriggerKeys(String[] keyArray) {
        List<TriggerKey> triggerKeys = new ArrayList<>();
        for (int i = 0; i < keyArray.length; i++) {
            String key = keyArray[i];
            triggerKeys.add(TriggerKey.triggerKey(key, TRIGGER_GROUP));
        }
        return triggerKeys;
    }

//    /**
//     * 启动一个作业
//     * @param cron
//     * @param endDate
//     * @param dataMap
//     * @param key
//     */
//    public static void start(String cron, Date endDate, String schemeSchedulId, EvaluationPlan evaluationPlan) {
//        String key = evaluationPlan.getGid()+schemeSchedulId;
//        JobDataMap dataMap = new JobDataMap();
//        dataMap.put("GID", evaluationPlan.getGid());
//        dataMap.put("DBMETAGID", evaluationPlan.getDbMetaGid());
//        JobDetail job = getJob(key,dataMap);
//        Trigger trigger = createTrigger(cron,key,endDate);
//        startScheduler(scheduler, job, trigger);
//    }
//
//    /**
//     * 启动多个作业
//     * @param cron
//     * @param endDate
//     * @param dataMap
//     * @param keyArray
//     */
//    public static void start(String cron, Date endDate, String schemeSchedulId,List<EvaluationPlan> evaluationPlanList) {
//        for (EvaluationPlan evaluationPlan : evaluationPlanList) {
//            start(cron, endDate, schemeSchedulId,evaluationPlan);
//        }
//    }
//
//    /**
//     * 添加一个作业
//     * @param cron
//     * @param endDate
//     * @param dataMap
//     * @param key
//     */
//    public static void add(String cron, Date endDate, JobDataMap dataMap, String key) {
//        JobDetail job = getJob(key,dataMap);
//        Trigger trigger = createTrigger(cron,key,endDate);
//        addScheduler(scheduler, job, trigger);
//    }

//    /**
//     * 添加多个作业
//     * @param cron
//     * @param endDate
//     * @param dataMap
//     * @param key
//     */
//    public static void add(String cron, Date endDate, JobDataMap dataMap, String keyArray[]) {
//        for (String key : keyArray) {
//            add(cron, endDate, dataMap, key);
//        }
//    }

    /**
     * 更新作业的表达式，截止时间
     * @param key
     * @param cron
     * @param endDate
     */
    public static void update(String key, String cron, Date endDate){
//        TriggerKey triggerKey = TriggerKey.triggerKey(key, TRIGGER_GROUP);
//        Trigger newTrigger = createTrigger(cron, key, endDate) ;
//        try {
//            scheduler.rescheduleJob(triggerKey, newTrigger);
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 更新作业的表达式，截止时间
     * @param keyArray
     * @param cron
     * @param endDate
     */
    public static void update(String[] keyArray, String cron, Date endDate){
        for (String key : keyArray) {
            update(key, cron, endDate);
        }
    }

    /**
     * 暂停一个作业调度
     * @param key
     */
    public static void pause(String key) {
//        try {
//            scheduler.pauseJob(JobKey.jobKey(key, JOB_GROUP));
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        }
    }

//    /**
//     * 暂停多个作业调度
//     * @param key
//     */
//    public static void pause(String[] keyArray) {
//        for (String key : keyArray) {
//            pause(key);
//        }
//    }

    /**
     * 恢复一个作业调度
     * @param key
     */
    public static void resume(String key) {
        JobKey jobKey = JobKey.jobKey(key, JOB_GROUP);
        JobDetail detail = null;
//        try {
//            detail = scheduler.getJobDetail(jobKey);
//        } catch (SchedulerException e1) {
//            e1.printStackTrace();
//        }
        if(detail==null){

        }else{
//            try {
////                scheduler.resumeJob(jobKey);
//            } catch (SchedulerException e) {
//                e.printStackTrace();
//            }
        }
    }

    /**
     * 恢复多个作业调度
     * @param keyArray
     */
    public static void resume(String[] keyArray) {
        for (String key : keyArray) {
            resume(key);
        }
    }

    /**
     * 移除一个作业调度
     * @param key
     */
    public static void remove(String key) {
//        try {
////            scheduler.unscheduleJob(TriggerKey.triggerKey(key, TRIGGER_GROUP));
////            scheduler.deleteJob(JobKey.jobKey(key, JOB_GROUP));
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        }
    }
//
//    /**
//     * 移除多个作业调度
//     * @param key
//     */
    public static void remove(String[] keyArray) {
        List<TriggerKey> triggerKeys = getTriggerKeys(keyArray);
        List<JobKey> jobKeys = getJobKeys(keyArray);
        for (int i = 0; i < keyArray.length; i++) {
            String key = keyArray[i];
            triggerKeys.add(TriggerKey.triggerKey(key, TRIGGER_GROUP));
            jobKeys.add(JobKey.jobKey(key, JOB_GROUP));
        }
//        try {
////            scheduler.unscheduleJobs(triggerKeys);
////            scheduler.deleteJobs(jobKeys);
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        }
    }

//    /**
//     * 启动/恢复 一个作业
//     * @param cron
//     * @param endDate
//     * @param dataMap
//     * @param key
//     */
//    public static void run(String cron, Date endDate,  String schemeSchedulId,EvaluationPlan evaluationPlan) {
//        String key = schemeSchedulId+evaluationPlan.getGid();
//        JobDetail detail = getDetail(key);
//        if(detail==null){
//            start(cron, endDate, schemeSchedulId,evaluationPlan);
//        }else{
//            resume(key);
//        }
//    }

    private final static String JOB_NAME = "TASK_";

    /**
     * 获取触发器key
     */
    public static TriggerKey getTriggerKey(String jobId) {
        return TriggerKey.triggerKey(JOB_NAME + jobId);
    }

    /**
     * 获取jobKey
     */
    public static JobKey getJobKey(String jobId) {
        return JobKey.jobKey(JOB_NAME + jobId);
    }

    /**
     * 获取表达式触发器
     */
    public static CronTrigger getCronTrigger(Scheduler scheduler, String jobId) {
        try {
            return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
        } catch (SchedulerException e) {
            throw new NullPointerException("获取定时任务CronTrigger出现异常");
        }
    }

    /**
     * 创建定时任务
     */
    public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
        try {
            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getId())).build();

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
                    .withMisfireHandlingInstructionDoNothing();

            //按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getId())).withSchedule(scheduleBuilder).build();

            //放入参数，运行时的方法可以获取
            jobDetail.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);

            scheduler.scheduleJob(jobDetail, trigger);

            //暂停任务
            if(scheduleJob.getDocStatus() == null){
                pauseJob(scheduler, scheduleJob.getId());
            }
        } catch (SchedulerException e) {
            throw new NullPointerException("创建定时任务失败");
        }
    }

    /**
     * 更新定时任务
     */
    public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
        try {
            TriggerKey triggerKey = getTriggerKey(scheduleJob.getId());

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
                    .withMisfireHandlingInstructionDoNothing();

            CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getId());

            //按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            //参数
            trigger.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);

            scheduler.rescheduleJob(triggerKey, trigger);

            //暂停任务
            if(scheduleJob.getDocStatus() == null){
                pauseJob(scheduler, scheduleJob.getId());
            }

        } catch (SchedulerException e) {
            throw new NullPointerException("删除定时任务失败");
        }
    }

    /**
     * 立即执行任务
     */
    public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) {
        try {
            //参数
            JobDataMap dataMap = new JobDataMap();
            dataMap.put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob);

            scheduler.triggerJob(getJobKey(scheduleJob.getId()), dataMap);
        } catch (SchedulerException e) {
            throw new NullPointerException("删除定时任务失败");
        }
    }

    /**
     * 暂停任务
     */
    public static void pauseJob(Scheduler scheduler, String jobId) {
        try {
            scheduler.pauseJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new NullPointerException("删除定时任务失败");
        }
    }

    /**
     * 恢复任务
     */
    public static void resumeJob(Scheduler scheduler, String jobId) {
        try {
            scheduler.resumeJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new NullPointerException("删除定时任务失败");
        }
    }

    /**
     * 删除定时任务
     */
    public static void deleteScheduleJob(Scheduler scheduler, String jobId) {
        try {
            scheduler.deleteJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new NullPointerException("删除定时任务失败");
        }
    }

    String cron = "* * 10 * * ?";
    JobKey jobKey = JobKey.jobKey("qwet1", "test");
    TriggerKey triggerKey = TriggerKey.triggerKey("qwet", "test");

    public void scheduler(Scheduler scheduler, ScheduleJobEntity scheduleJob) throws Exception {
        CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing();
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronSchedule).build();
        JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(jobKey).build();
        jobDetail.getJobDataMap().put("JOB_PARAM_KEY", scheduleJob);
       // scheduler.addJob(jobDetail, true);
        scheduler.scheduleJob(jobDetail, trigger);
        TimeUnit.SECONDS.sleep(5);
//        this.start(scheduler);
      //  this.stop(scheduler);
        //scheduler.rescheduleJob(triggerKey, trigger);
//        this.run(scheduler);
//        this.delete(scheduler);
//        scheduler.scheduleJob(jobDetail, trigger);
//        this.stand(scheduler);
//        this.start(scheduler);
        System.out.println(scheduler.isShutdown());
    }

    void start(Scheduler scheduler) throws SchedulerException, InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("start任务");
        scheduler.standby();
        System.out.println("start任务成功");
    }

    void stand(Scheduler scheduler) throws SchedulerException, InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("stand任务");
        scheduler.standby();
        System.out.println("stand任务成功");
    }

    void stop(Scheduler scheduler) throws SchedulerException, InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("暂停任务");
        scheduler.pauseJob(jobKey);
        System.out.println("暂停任务成功");
    }

    void rest(Scheduler scheduler) throws SchedulerException, InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("恢复任务");
        scheduler.resumeJob(jobKey);
        System.out.println("恢复任务成功");
    }

    void delete(Scheduler scheduler) throws SchedulerException, InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        System.out.println("删除任务");
        scheduler.deleteJob(jobKey);
        System.out.println("删除任务成功");
    }

    void run(Scheduler scheduler) throws SchedulerException, InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("立即执行任务");
        scheduler.triggerJob(jobKey);
        System.out.println("立即执行任务成功");
    }

}
